﻿using System;
using System.Linq;
using System.Text;
using System.Net;
using P2P_Backup.connections;
using System.Net.Sockets;
using System.Xml.Serialization;
namespace P2P_Backup
{ 
    public class RemotePeer : Peer
    {
        [XmlIgnore]
        public bool PerformBackup;
        
        private RemotePeerConnection connection;
        public RemotePeer()
        {

        }

        public RemotePeer(IPAddress ipAddress, String hostname = null,TcpClient tcpClient = null)
        {
            base.IpAddress = ipAddress;
            base.Hostname = hostname;
            if (tcpClient != null)
            {
                //happens when the peer connects to you
                connection = new RemotePeerConnection(tcpClient);
            }
            else
            {
                //happens when you get an announcment
                connection = new RemotePeerConnection(ipAddress);                
            }
            connection.dataReceived += new EventHandler<tools.net.DataEventArgs>(connection_dataReceived);
            connection.disconnect += new EventHandler(connection_disconnect);
            sendCommand("HST", P2PBackup.Instance.Local.Hostname);
            sendCommand("FBS", P2PBackup.Instance.Local.FreeBackupSpace.ToString());            
        }

        private void connection_disconnect(object sender, EventArgs e)
        {
            P2PBackup.Instance.Peers.Remove(this);
            Console.WriteLine("Peer {0} disconnected", this);            
        }

        private void connection_dataReceived(object sender, tools.net.DataEventArgs e)
        {
            switch (e.Data[0])
            {
                case "HST":
                    base.Hostname = e.Data[1];
                    Console.WriteLine("{0} anncounced itself as {1}", base.IpAddress, base.Hostname);
                    P2PBackup.Instance.Peers.Add(this);
                    break;
                case "FBS":
                    this.FreeBackupSpace = long.Parse(e.Data[1]);
                    Console.WriteLine("{0} has {1} free bytes", base.Hostname,this.FreeBackupSpace);
                    break;
                case "CLS":
                    connection.Close();
                    break;

                case "BFT"://Backup File Transfer
                    Console.WriteLine("Recieved incoming Backup File Transfer from {0}", this.Hostname);
                    archive.ArchivedFile archFile = new archive.ArchivedFile(this,e.Data[1],e.Data[2]);
                    IPEndPoint backEndPoint = tools.net.CreateIPEndPoint(this.IpAddress,e.Data[3]);
                    RemoteFileConnection remFileConn = new RemoteFileConnection(archFile, backEndPoint);
                    break;

                case "RRQ"://Restore Request
                    string fileId = e.Data[1];
                    archive.File remFile = new archive.ArchivedFile(this, e.Data[1], e.Data[2]);
                    LocalFileConnection locFileConn = new LocalFileConnection(remFile);
                    sendCommand("RFT",String.Format("{0} {1} {2}", e.Data[1], e.Data[2], locFileConn.EndPoint.Port));
                    break;

                case "RFT"://Restore File Transfer                          
                    archive.File resFile = (e.Data[1] == "data")
                        ? new archive.DataFile(this)
                        : P2PBackup.Instance.MyArchive.FindFile(e.Data[1]);
                    IPEndPoint resEndPoint = tools.net.CreateIPEndPoint(this.IpAddress, e.Data[3]);                    
                    RemoteFileConnection resFileConn = new RemoteFileConnection(resFile, resEndPoint);
                    break;
            }
        }
      

        public void sendCommand(string command,string args = "")
        {
            connection.sendText(String.Format("{0} {1} ", command, args));            
        }
    }
}
